package com.fzu.express.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzu.express.annotation.SystemLog;
import com.fzu.express.entity.Order;
import com.fzu.express.entity.Outlet;
import com.fzu.express.entity.WebUser;
import com.fzu.express.enums.EnableStatusEnum;
import com.fzu.express.enums.OrderStatusEnum;
import com.fzu.express.enums.RoleEnum;
import com.fzu.express.mapper.OrderMapper;
import com.fzu.express.mapper.OutletMapper;
import com.fzu.express.mapper.WebUserMapper;
import com.fzu.express.pojo.PasswordDTO;
import com.fzu.express.pojo.RegisterDTO;
import com.fzu.express.pojo.UserDTO;
import com.fzu.express.pojo.UserVO;
import com.fzu.express.service.WebUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzu.express.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zyq
 * @since 2022-10-27
 */
@Service
public class WebUserServiceImpl extends ServiceImpl<WebUserMapper, WebUser> implements WebUserService {

    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OutletMapper outletMapper;

    @Override
    @SystemLog(businessName = "登陆")
    public UserVO login(UserDTO userDTO) {
        String phone = userDTO.getPhone();
        String password = userDTO.getPassword();

        WebUser user = this.getByPhone(phone);
        // 判断账号是否存在并验证密码
        if (user == null || !PasswordUtil.match(password, user.getPassword())) {
            throw new ApiException(ErrorEnum.USER_NO_EXIST);
        }

        // 使用account生成token
        String token = JwtUtil.getToken(phone);

        // 网点管理员和快递需要判断网点是否禁用
        Integer role = user.getRole();
        if (RoleEnum.OUTLET_MANAGER.getCode().equals(role) || RoleEnum.COURIER.getCode().equals(role)) {
            Outlet outlet = outletMapper.selectById(user.getOutletId());
            if (EnableStatusEnum.DISABLE.getCode().equals(outlet.getStatus())) {
                throw new ApiException("您所在网点已被禁用，请联系管理员");
            }
        }

        return new UserVO()
                .setName(user.getName())
                .setRole(user.getRole())
                .setOutletId(user.getOutletId())
                .setId(user.getId())
                .setPhone(user.getPhone())
                .setCreateTime(user.getCreateTime())
                .setToken(token);
    }

    @Override
    @SystemLog(businessName = "注册")
    public void register(RegisterDTO registerDTO) {
        String phone = registerDTO.getPhone();
        // 手机号码格式校验
        if (!CommonUtil.validPhone(phone)) {
            throw new ApiException(ErrorEnum.PHONE_FORMAT_ERROR);
        }
        WebUser user = this.getByPhone(phone);
        if (user != null) {
            throw new ApiException(ErrorEnum.ACCOUNT_REGISTERED);
        }

        WebUser webUser = new WebUser().setPhone(phone)
                .setPassword(PasswordUtil.encode(registerDTO.getPassword()))
                .setName(registerDTO.getName())
                .setDeleted(EnableStatusEnum.DISABLE.getCode())
                .setRole(RoleEnum.USER.getCode());
        super.save(webUser);
    }


    /**
     * 根据账号获取用户
     * @param phone 账号(手机号码)
     * @return webUser
     */
    private WebUser getByPhone(String phone) {
        LambdaQueryWrapper<WebUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WebUser::getPhone, phone);
        return super.getOne(lambdaQueryWrapper);
    }

    @Override
    public PageVO listWebUser(WebUser webuser, WebUser currentUser, Integer pageNum, Integer pageSize) {
        // 构造分页参数
        Page<WebUser> pageRequest = new Page<>(pageNum, pageSize);

        // 构造条件查询器
        LambdaQueryWrapper<WebUser> wrapper = new LambdaQueryWrapper<>();
        // 结合实际场景，可根据订单号，订单状态，发件人手机号，收件人手机号进行订单查询
        // 对条件进行非空判断，不为空时添加查询条件
        // 字符串的非空判断统一使用org.apache.commons.lang3.StringUtils.isNotBlank()
        // 其他类型的非空判断统一使用 != null


        // 姓名
        String name = webuser.getName();
        if (StringUtils.isNotBlank(name)) {
            wrapper.eq(WebUser::getName, name);
        }

        // 账号
        String account = webuser.getAccount();
        if (StringUtils.isNotBlank(account)){
            wrapper.eq(WebUser::getAccount, account);
        }

        // 账号（手机号码）
        String phone = webuser.getPhone();
        if (StringUtils.isNotBlank(phone)){
            wrapper.eq(WebUser::getPhone, phone);
        }

        // 角色类型
        Integer role = webuser.getRole();
        if ( role != null ) {
            wrapper.eq(WebUser::getRole, role);
        }

        // 所属网点
        Long outletId = webuser.getOutletId();
        if (outletId != null) {
            wrapper.eq(WebUser::getOutletId, outletId);
        }

        // 添加用户身份条件
        if (RoleEnum.OUTLET_MANAGER.getCode().equals(currentUser.getRole())) {
            wrapper.eq(WebUser::getOutletId, currentUser.getOutletId())
                    .eq(WebUser::getRole, RoleEnum.COURIER.getCode());
        }

        // 进行查询
        IPage<WebUser> page = super.page(pageRequest, wrapper);
        return PageVO.convert(page);
    }

    @Override
    public void addWebUser(WebUser webuser) {
        String phone = webuser.getPhone();
        // 手机号码格式校验
        if (!CommonUtil.validPhone(phone)) {
            throw new ApiException(ErrorEnum.PHONE_FORMAT_ERROR);
        }
        WebUser user = this.getByPhone(phone);
        if (user != null) {
            throw new ApiException(ErrorEnum.ACCOUNT_REGISTERED);
        }
        // 对新密码加密并赋值
        webuser.setPassword(PasswordUtil.encode(webuser.getPassword()));
        super.save(webuser);
    }

    @Override
    public void updateWebUser(WebUser webuser) {
        // 更新是根据id确定记录的，所以必须对id进行非空判断
        if (webuser.getId() == null) {
            throw new ApiException("ID值不能为空");
        }
        super.updateById(webuser);
    }

    @Override
    public void deleteWebUser(Long id) {
        WebUser user = super.getById(id);
        Integer role = user.getRole();
        if (RoleEnum.OUTLET_MANAGER.getCode().equals(role)) {
            throw new ApiException("无法删除网点管理员账号");
        }
        if (RoleEnum.COURIER.getCode().equals(role)) {
            LambdaQueryWrapper<Order> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.and(w ->
                    w.eq(Order::getStartCourier, user.getId())
                            .or()
                            .eq(Order::getEndCourier, user.getId()))
                    .and(w -> w.eq(Order::getStatus, OrderStatusEnum.CANCELED.getCode())
                            .or().eq(Order::getStatus, OrderStatusEnum.FINISH.getCode()));
            Integer res = orderMapper.selectCount(lambdaQueryWrapper);
            if (res > 0) {
                throw new ApiException("该快递员存在未完成的快递，无法删除");
            }
        }
        super.removeById(id);
    }

    @Override
    public void updatePassword(PasswordDTO passwordDTO, WebUser user) {
        String oldPassword = passwordDTO.getOldPassword();
        String newPassword = passwordDTO.getNewPassword();

        // 原密码判断
        boolean match = PasswordUtil.match(oldPassword, user.getPassword());
        if (!match) {
            throw new ApiException("原密码不正确");
        }
        // 对新密码加密并赋值
        user.setPassword(PasswordUtil.encode(newPassword));
        super.updateById(user);
    }

}
